import { Init, Inject, Provide } from '@midwayjs/core';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { GoodsPromoMtEntity } from '../entity/promo_mt';
import { GoodsPromoTcEntity } from '../entity/promo_tc';
import { GoodsPromoMsEntity } from '../entity/promo_ms';
import { GoodsPromoMzEntity } from '../entity/promo_mz';
import { GoodsInfoEntity } from '../entity/info';
import { OrderInfoEntity } from '../../order/entity/info';
import { OrderGoodsEntity } from '../../order/entity/goods';
import { OrderInfoService } from '../../order/service/info';
import { OracleService } from '../../../comm/service/oracle.service';
import { TrimUtil } from '../../../comm/service/trim.util';
import * as moment from 'moment';
import * as oracledb from 'oracledb';

/**
 * 促销订单服务
 */
@Provide()
export class GoodsPromoOrderService extends BaseService {
  @InjectEntityModel(GoodsPromoMtEntity)
  promoMtEntity: Repository<GoodsPromoMtEntity>;

  @InjectEntityModel(GoodsPromoTcEntity)
  promoTcEntity: Repository<GoodsPromoTcEntity>;

  @InjectEntityModel(GoodsPromoMsEntity)
  promoMsEntity: Repository<GoodsPromoMsEntity>;

  @InjectEntityModel(GoodsPromoMzEntity)
  promoMzEntity: Repository<GoodsPromoMzEntity>;

  @InjectEntityModel(GoodsInfoEntity)
  goodsInfoEntity: Repository<GoodsInfoEntity>;

  @InjectEntityModel(OrderInfoEntity)
  orderInfoEntity: Repository<OrderInfoEntity>;

  @InjectEntityModel(OrderGoodsEntity)
  orderGoodsEntity: Repository<OrderGoodsEntity>;

  @Inject()
  orderInfoService: OrderInfoService;

  @Inject()
  oracleService: OracleService;

  @Init()
  async init() {
    await super.init();
  }

  /**
   * 创建促销订单 - 套餐类型(TC)
   * @param userId 用户ID
   * @param billNo 促销单据号
   * @param remark 备注
   */
  async createComboOrder(userId: string, billNo: string, remark?: string) {
    // 1. 验证促销活动有效性
    const promo = await this.validatePromo(billNo, 'TC');
    
    // 2. 获取套餐明细
    const comboDetails = await this.promoTcEntity.find({
      where: { billNo, status: 1 },
      order: { billSn: 'ASC' }
    });

    if (!comboDetails || comboDetails.length === 0) {
      throw new CoolCommException('套餐明细不存在');
    }

    // 3. 检查库存并构建订单商品
    const goodsList = await this.buildOrderGoodsFromCombo(comboDetails, userId);

    // 4. 计算套餐总价
    const totalPrice = comboDetails.reduce((sum, detail) => 
      sum + (Number(detail.taxprice) * Number(detail.num)), 0
    );

    // 5. 创建订单
    const orderData = {
      userId,
      goodsList,
      remark: remark || `套餐订单：${promo.promName}`,
      title: `套餐：${promo.promName}`,
    };

    // 使用自定义的创建方法，跳过价格检查
    const order = await this.createPromoOrderDirect(orderData, totalPrice, 'TC', billNo);

    return order;
  }

  /**
   * 创建促销订单 - 秒杀类型(MS)
   * @param userId 用户ID
   * @param billNo 促销单据号
   * @param goodsId 商品ID
   * @param quantity 购买数量
   * @param remark 备注
   */
  async createSeckillOrder(userId: string, billNo: string, goodsId: string, quantity: number, remark?: string) {
    // 1. 验证促销活动有效性
    const promo = await this.validatePromo(billNo, 'MS');
    
    // 2. 获取秒杀明细
    const seckillDetail = await this.promoMsEntity.findOne({
      where: { billNo, goodsId, status: 1 }
    });

    if (!seckillDetail) {
      throw new CoolCommException('秒杀商品不存在');
    }

    // 3. 检查秒杀库存
    if (quantity > Number(seckillDetail.seckillStorNum)) {
      throw new CoolCommException('秒杀库存不足');
    }

    // 4. 检查秒杀数量限制
    if (quantity > Number(seckillDetail.seckillNum)) {
      throw new CoolCommException(`每人限购${seckillDetail.seckillNum}件`);
    }

    // 5. 获取商品信息
    const goodsInfo = await this.goodsInfoEntity.findOne({
      where: { goodsId }
    });

    if (!goodsInfo) {
      throw new CoolCommException('商品不存在');
    }

    // 6. 构建订单商品
    const orderGoods: OrderGoodsEntity = {
      goodsId,
      price: Number(seckillDetail.seckillPrice),
      count: quantity,
      discountPrice: 0,
      remark: '秒杀商品',
      goodsInfo,
      spec: null,
      isComment: 0
    } as OrderGoodsEntity;

    // 7. 计算总价
    const totalPrice = Number(seckillDetail.seckillPrice) * quantity;

    // 8. 创建订单
    const orderData = {
      userId,
      goodsList: [orderGoods],
      remark: remark || `秒杀订单：${promo.promName}`,
      title: `秒杀：${promo.promName}`,
    };

    const order = await this.createPromoOrderDirect(orderData, totalPrice, 'MS', billNo);

    // 9. 更新秒杀库存
    await this.promoMsEntity.update(
      { billNo, goodsId },
      { seckillStorNum: Number(seckillDetail.seckillStorNum) - quantity }
    );

    return order;
  }

  /**
   * 创建促销订单 - 买赠类型(MZ)
   * @param userId 用户ID
   * @param billNo 促销单据号
   * @param goodsId 购买商品ID
   * @param quantity 购买数量
   * @param remark 备注
   */
  async createBuyGiftOrder(userId: string, billNo: string, goodsId: string, quantity: number, remark?: string) {
    // 1. 验证促销活动有效性
    const promo = await this.validatePromo(billNo, 'MZ');
    
    // 2. 获取买赠明细
    const buyGiftDetail = await this.promoMzEntity.findOne({
      where: { billNo, goodsId, status: 1 }
    });

    if (!buyGiftDetail) {
      throw new CoolCommException('买赠商品不存在');
    }

    // 3. 检查购买数量是否满足条件
    if (quantity < Number(buyGiftDetail.num)) {
      throw new CoolCommException(`至少需要购买${buyGiftDetail.num}件才能享受买赠优惠`);
    }

    // 4. 获取购买商品和赠品信息
    const [buyGoodsInfo, freeGoodsInfo] = await Promise.all([
      this.goodsInfoEntity.findOne({ where: { goodsId } }),
      this.goodsInfoEntity.findOne({ where: { goodsId: buyGiftDetail.freeId } })
    ]);

    if (!buyGoodsInfo || !freeGoodsInfo) {
      throw new CoolCommException('商品信息不存在');
    }

    // 5. 检查库存
    await this.checkGoodsStock(goodsId, quantity, userId);
    await this.checkGoodsStock(buyGiftDetail.freeId, Number(buyGiftDetail.freeNum), userId);

    // 6. 构建订单商品（购买商品 + 赠品）
    const buyGoods: OrderGoodsEntity = {
      goodsId,
      price: Number(buyGiftDetail.taxprice),
      count: quantity,
      discountPrice: 0,
      remark: '买赠主商品',
      goodsInfo: buyGoodsInfo,
      spec: null,
      isComment: 0
    } as OrderGoodsEntity;

    const freeGoods: OrderGoodsEntity = {
      goodsId: buyGiftDetail.freeId,
      price: Number(buyGiftDetail.freeTaxPrice),
      count: Number(buyGiftDetail.freeNum),
      discountPrice: 0,
      remark: '买赠赠品',
      goodsInfo: freeGoodsInfo,
      spec: null,
      isComment: 0
    } as OrderGoodsEntity;

    // 7. 计算总价（购买商品价格 + 赠品价格）
    const buyGoodsPrice = Number(buyGiftDetail.taxprice) * quantity;
    const freeGoodsPrice = Number(buyGiftDetail.freeTaxPrice) * Number(buyGiftDetail.freeNum);
    const totalPrice = buyGoodsPrice + freeGoodsPrice;

    // 8. 创建订单
    const orderData = {
      userId,
      goodsList: [buyGoods, freeGoods],
      remark: remark || `买赠订单：${promo.promName}`,
      title: `买赠：${promo.promName}`,
    };

    const order = await this.createPromoOrderDirect(orderData, totalPrice, 'MZ', billNo);

    return order;
  }

  /**
   * 验证促销活动有效性
   */
  private async validatePromo(billNo: string, expectedType: string) {
    const promo = await this.promoMtEntity.findOne({
      where: { billNo }
    });

    if (!promo) {
      throw new CoolCommException('促销活动不存在');
    }

    if (promo.status !== 1) {
      throw new CoolCommException('促销活动已停用');
    }

    const now = new Date();
    if (promo.startTime && now < promo.startTime) {
      throw new CoolCommException('促销活动尚未开始');
    }

    if (promo.endTime && now > promo.endTime) {
      throw new CoolCommException('促销活动已结束');
    }

    // 验证促销类型
    const typeMap = {
      'TC': '套餐',
      'MS': '秒杀', 
      'MZ': '买赠'
    };

    if (promo.promType !== typeMap[expectedType]) {
      throw new CoolCommException(`促销类型不匹配，期望：${typeMap[expectedType]}，实际：${promo.promType}`);
    }

    return promo;
  }

  /**
   * 从套餐明细构建订单商品
   */
  private async buildOrderGoodsFromCombo(comboDetails: GoodsPromoTcEntity[], userId: string): Promise<OrderGoodsEntity[]> {
    const goodsList: OrderGoodsEntity[] = [];

    for (const detail of comboDetails) {
      // 获取商品信息
      const goodsInfo = await this.goodsInfoEntity.findOne({
        where: { goodsId: detail.goodsId }
      });

      if (!goodsInfo) {
        throw new CoolCommException(`商品${detail.goodsId}不存在`);
      }

      // 检查库存
      await this.checkGoodsStock(detail.goodsId, Number(detail.num), userId);

      // 构建订单商品
      const orderGoods: OrderGoodsEntity = {
        goodsId: detail.goodsId,
        price: Number(detail.taxprice),
        count: Number(detail.num),
        discountPrice: 0,
        remark: '套餐商品',
        goodsInfo,
        spec: null,
        isComment: 0
      } as OrderGoodsEntity;

      goodsList.push(orderGoods);
    }

    return goodsList;
  }

  /**
   * 检查商品库存
   */
  private async checkGoodsStock(goodsId: string, quantity: number, userId: string) {
    const dataSource = this.oracleService.getDataSource();
    if (!dataSource || !dataSource.isInitialized) {
      throw new CoolCommException('Oracle数据源不可用');
    }

    let connection: oracledb.Connection | undefined;
    try {
      const driver = dataSource.driver as any;
      const pool = driver.pool || driver.master;
      if (!pool || typeof pool.getConnection !== 'function') {
        throw new CoolCommException('无法获取数据库连接');
      }
      
      connection = await pool.getConnection();

      // 确保输入参数为字符串类型并添加maxSize
      const goodsIdStr = String(goodsId).trim();
      const userIdStr = String(userId).trim();

      const bindParams: oracledb.BindParameters = {
        DATASET: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
        yxc_b2b_goodsid: { type: oracledb.STRING, dir: oracledb.BIND_IN, val: goodsIdStr, maxSize: 100 },
        yxc_b2b_clientid: { type: oracledb.STRING, dir: oracledb.BIND_IN, val: userIdStr, maxSize: 100 }
      };

      const result = await connection.execute<{ DATASET: oracledb.ResultSet<any> }>(
        `BEGIN YXC_B2B_SP_BALANCE_PRICE(:DATASET, :yxc_b2b_goodsid, :yxc_b2b_clientid); END;`,
        bindParams,
        { 
          outFormat: oracledb.OUT_FORMAT_OBJECT,
          autoCommit: true
        }
      );

      if (result && result.outBinds && result.outBinds.DATASET) {
        const resultSet = result.outBinds.DATASET;
        if (resultSet && typeof resultSet.getRows === 'function') {
          const rows = await resultSet.getRows();
          await resultSet.close();
          
          if (rows && rows.length > 0) {
            const stock = Number(rows[0].STORNUM || 0);
            if (quantity > stock) {
              const goodsInfo = await this.goodsInfoEntity.findOne({ where: { goodsId } });
              throw new CoolCommException(`商品[${goodsInfo?.title || goodsId}]库存不足，当前库存：${stock}`);
            }
          } else {
            throw new CoolCommException('无法获取商品库存信息');
          }
        }
      }
    } catch (error) {
      console.log('检查商品库存失败:', error);
      throw new CoolCommException('检查商品库存失败: ' + error.message);
    } finally {
      if (connection) {
        try {
          await connection.close();
        } catch (error) {
          console.error('关闭数据库连接失败:', error);
        }
      }
    }
  }

  /**
   * 直接创建促销订单（跳过常规价格检查）
   */
  private async createPromoOrderDirect(
    orderData: {
      userId: string;
      goodsList: OrderGoodsEntity[];
      remark?: string;
      title?: string;
    },
    totalPrice: number,
    promoType: string,
    billNo: string
  ) {
    // 创建订单实体
    const orderEntity = this.orderInfoEntity.create({
      userId: orderData.userId,
      remark: orderData.remark || '',
      title: orderData.title,
      price: totalPrice,
      discountPrice: 0,
      status: 0, // 待付款
      payType: 0, // 待支付
      invoice: 0, // 未开票
      wxType: 0, // 默认小程序
    });

    // 保存订单并获取ID
    const savedOrder = await this.orderInfoEntity.save(orderEntity);
    console.log('促销订单创建成功，订单ID:', savedOrder.id);

    // 生成订单号
    const orderNum = await this.orderInfoService.generateOrderNum(savedOrder.id, 'P'); // P表示促销订单
    console.log('促销订单号生成:', orderNum);

    // 更新订单号
    await this.orderInfoEntity.update(savedOrder.id, { orderNum });

    // 保存订单商品
    const savedGoodsList = [];
    for (const goods of orderData.goodsList) {
      const orderGoods = this.orderGoodsEntity.create({
        orderId: savedOrder.id,
        goodsId: goods.goodsId,
        price: goods.price,
        count: goods.count,
        discountPrice: goods.discountPrice || 0,
        remark: goods.remark || '',
        goodsInfo: goods.goodsInfo,
        spec: goods.spec,
        isComment: 0
      });
      const savedGoods = await this.orderGoodsEntity.save(orderGoods);
      savedGoodsList.push(savedGoods);
      console.log('促销订单商品保存成功:', savedGoods.id, goods.goodsId);
    }

    // 同步到Oracle
    try {
      await this.insertPromoOrderToOracle(orderNum, orderData.userId, savedGoodsList, promoType, billNo);
      console.log('促销订单同步到Oracle成功');
    } catch (oracleError) {
      console.error('促销订单同步到Oracle失败:', oracleError);
      // Oracle同步失败不影响本地订单创建
    }

    return { 
      ...savedOrder, 
      orderNum,
      goodsList: savedGoodsList
    };
  }

  /**
   * 插入促销订单到Oracle
   */
  private async insertPromoOrderToOracle(
    orderNum: string,
    userId: string,
    goodsList: OrderGoodsEntity[],
    promoType: string,
    billNo: string
  ) {
    const dataSource = this.oracleService.getDataSource();
    if (!dataSource || !dataSource.isInitialized) {
      throw new CoolCommException('Oracle数据源不可用');
    }

    const queryRunner = dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const now = new Date();
      const dates = moment(now).format('YYYY-MM-DD');
      const ontime = moment(now).format('HH:mm:ss');

      for (let i = 0; i < goodsList.length; i++) {
        const goods = goodsList[i];
        const insertSql = `INSERT INTO YXC_B2B_ORDERLIST (
          orderno, dates, ontime, businessid, goodsid, taxprice, num, taxamount, 
          billstate, ordertype, ordersn, execnum, isdone, logistate, 
          hightaxprice, dedrate, staffid, orgid
        ) VALUES (
          :1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16, :17, :18
        )`;

        const [trimmedOrderNum, trimmedUserId, trimmedGoodsId] = 
          TrimUtil.trimMultiple(orderNum, userId, goods.goodsId);

        // 确保所有参数类型正确
        const params = [
          String(trimmedOrderNum),                              // :1 orderno
          String(dates),                                        // :2 dates
          String(ontime),                                       // :3 ontime
          String(trimmedUserId),                               // :4 businessid
          String(trimmedGoodsId),                              // :5 goodsid
          Number(goods.price),                                 // :6 taxprice
          Number(goods.count),                                 // :7 num
          Number(goods.price) * Number(goods.count),           // :8 taxamount
          Number(0),                                           // :9 billstate
          String(`促销订单-${promoType}`),                      // :10 ordertype (在这里标识促销类型)
          Number(i),                                           // :11 ordersn
          Number(0),                                           // :12 execnum
          String('N'),                                         // :13 isdone
          Number(1),                                           // :14 logistate
          Number(0),                                           // :15 hightaxprice
          Number(0),                                           // :16 dedrate
          null,                                                // :17 staffid
          null                                                 // :18 orgid
        ];

        await queryRunner.query(insertSql, params);
      }

      await queryRunner.commitTransaction();
    } catch (err) {
      await queryRunner.rollbackTransaction();
      console.error('插入Oracle促销订单失败:', err);
      throw new CoolCommException('插入Oracle促销订单失败: ' + err.message);
    } finally {
      await queryRunner.release();
    }
  }
} 